package cn.peifu.hrm.service.impl;

import cn.peifu.hrm.CourseDoc;
import cn.peifu.hrm.constants.BaseConstants;
import cn.peifu.hrm.domain.Course;
import cn.peifu.hrm.domain.CourseDetail;
import cn.peifu.hrm.domain.CourseMarket;
import cn.peifu.hrm.domain.CourseType;
import cn.peifu.hrm.dto.CourseDto;
import cn.peifu.hrm.exception.code.ErrorCode;
import cn.peifu.hrm.feign.CourseFeign;
import cn.peifu.hrm.mapper.CourseDetailMapper;
import cn.peifu.hrm.mapper.CourseMapper;
import cn.peifu.hrm.mapper.CourseMarketMapper;
import cn.peifu.hrm.mapper.CourseTypeMapper;
import cn.peifu.hrm.service.ICourseService;
import cn.peifu.hrm.to.CourseEmailTo;
import cn.peifu.hrm.to.CourseSmsTo;
import cn.peifu.hrm.to.LoginInfoTo;
import cn.peifu.hrm.to.StationMsgTo;
import cn.peifu.hrm.util.AjaxResult;
import cn.peifu.hrm.util.AssertUtils;
import cn.peifu.hrm.util.LoginContext;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xie
 * @since 2021-08-19
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {

    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private CourseDetailMapper courseDetailMapper;
    @Autowired
    private CourseMarketMapper courseMarketMapper;
    @Autowired
    private CourseTypeMapper courseTypeMapper;

    @Autowired
    private CourseFeign courseFeign;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    @Transactional(readOnly = false,propagation = Propagation.REQUIRED)
    public void save(CourseDto dto) {
        // 获取前端传递的数据
        Course course = dto.getCourse();
        CourseDetail courseDetail = dto.getCourseDetail();
        CourseMarket courseMarket = dto.getCourseMarket();
        // 校验参数是否合法
        checkParam(course, courseDetail, courseMarket);
        // 保存course
        course.setStatus(BaseConstants.CourseConstants.STATE_OFFLINE);
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //LoginInfoTo login = JSONObject.parseObject(JSONObject.toJSONString(authentication.getPrincipal()), LoginInfoTo.class);
        //抽取工具类
        LoginInfoTo login = LoginContext.getLogin();
        course.setUserId(login.getUserId());
        course.setUserName(login.getUsername());
        course.setTenantId(login.getTenantId());
        course.setTenantName(login.getTenantName());
        super.insert(course);
        // 保存courseDetail
        courseDetail.setId(course.getId());
        courseDetailMapper.insert(courseDetail);
        // 保存courseMarket
        courseMarket.setId(course.getId());
        courseMarketMapper.insert(courseMarket);
        // 课程类型+1
        CourseType courseType = courseTypeMapper.selectById(course.getCourseTypeId());
        courseType.setTotalCount(courseType.getTotalCount()+1);
        courseTypeMapper.updateById(courseType);
    }

    /**
     * 课程发布
     * @param id
     */
    @Override
    @Transactional(readOnly = false,propagation = Propagation.REQUIRED)
    public void onLineCourse(Long id) {
        AssertUtils.isNull(id,ErrorCode.CODE_204_NULL_COURSE_ID.getMessage());
        //根据id查询课程
        Course course = super.selectById(id);
        AssertUtils.isNull(course,ErrorCode.CODE_200_NULL_COURSE.getMessage());
        //判断课程是否是下架状态,如果不是就报错
        AssertUtils.isFalse(course.getStatus()==BaseConstants.CourseConstants.STATE_OFFLINE,
                ErrorCode.CODE_204_NULL_COURSE_ID.getMessage());
        //根据id查询课程market
        CourseMarket courseMarket = courseMarketMapper.selectById(id);
        //修改课程状态 -->上架
        course.setStatus(BaseConstants.CourseConstants.STATE_ONLINE);
        Date now = new Date();
        course.setOnlineTime(now);
        super.updateById(course);
        //Es存储数据
        CourseDoc courseDoc = new CourseDoc();
        BeanUtils.copyProperties(course,courseDoc);
        BeanUtils.copyProperties(courseMarket,courseDoc);
        //价格格式问题，单独设置
        if(courseMarket.getPrice()!=null || courseMarket.getPriceOld()!=null){
            courseDoc.setPrice(courseMarket.getPrice().doubleValue());
            courseDoc.setPriceOld(courseMarket.getPriceOld().doubleValue());
        }
        AjaxResult ajaxResult = courseFeign.save2Es(courseDoc);
        AssertUtils.isFalse(ajaxResult.isSuccess(),ajaxResult.getMessage());
        //发布消息
        sendAD(course, now);
    }

    /**
     * MQ发送3类消息
     * @param course
     * @param now
     */
    private void sendAD(Course course, Date now) {
        //短信方式
        String contentSms = "全成都最大的IT培训平台，现新开【"+ course.getName()+"】课程，马上咨询了解详情！";
        List<String> phones = Arrays.asList("17628294511","17628294519");
        rabbitTemplate.convertAndSend(BaseConstants.CourseConstants.EXCHANGE_TOPICS_COURSE,
                "course.sms",new CourseSmsTo(contentSms,phones));
        //邮件方式
        String contentEmail = "全成都最大的IT培训上线啦，现新开【"+ course.getName()+"】，马上咨询了解详情！";
        List<String> emails = Arrays.asList("17628294511","17628294519");
        rabbitTemplate.convertAndSend(BaseConstants.CourseConstants.EXCHANGE_TOPICS_COURSE,
                "course.email",new CourseEmailTo(contentEmail,emails));
        //站内信
        StationMsgTo stationMsgTo = new StationMsgTo();
        stationMsgTo.setContent("全成都最大的IT培训上线啦，现新开【"+ course.getName()+"】，马上咨询了解详情！");
        stationMsgTo.setState(1);
        stationMsgTo.setTime(now);
        stationMsgTo.setTitle("课程提示");
        stationMsgTo.setType("系统消息");
        stationMsgTo.setUserId(Arrays.asList(1L,2L,3L));
        rabbitTemplate.convertAndSend(BaseConstants.CourseConstants.EXCHANGE_TOPICS_COURSE,
                "course.station",stationMsgTo);
    }

    /**
     * 课程下架
     * @param id
     */
    @Override
    @Transactional(readOnly = false,propagation = Propagation.REQUIRED)
    public void offLineCourse(Long id) {
        AssertUtils.isNull(id,ErrorCode.CODE_204_NULL_COURSE_ID.getMessage());
        //根据id查询课程
        Course course = super.selectById(id);
        AssertUtils.isNull(course,ErrorCode.CODE_200_NULL_COURSE.getMessage());
        //判断课程是否是上架状态,如果不是就报错
        AssertUtils.isFalse(course.getStatus()==BaseConstants.CourseConstants.STATE_ONLINE,
                ErrorCode.CODE_204_NULL_COURSE_ID.getMessage());
        //修改课程状态 -->下架
        course.setStatus(BaseConstants.CourseConstants.STATE_OFFLINE);
        course.setOfflineTime(new Date());
        super.updateById(course);
        //Es存储数据
        CourseDoc courseDoc = new CourseDoc();
        BeanUtils.copyProperties(course,courseDoc);
        AjaxResult ajaxResult = courseFeign.save2Es(courseDoc);
        AssertUtils.isFalse(ajaxResult.isSuccess(),ajaxResult.getMessage());
    }


    /**
     *  校验参数是否合法
     * @param course
     * @param courseDetail
     * @param courseMarket
     */
    private void checkParam(Course course, CourseDetail courseDetail, CourseMarket courseMarket) {
        //空判断
        AssertUtils.isNull(course, ErrorCode.CODE_200_NULL_COURSE.getMessage());
        AssertUtils.isNull(courseDetail, ErrorCode.CODE_201_NULL_COURSE_DETAIL.getMessage());
        AssertUtils.isNull(courseMarket, ErrorCode.CODE_202_NULL_COURSE_MARKET.getMessage());
        //校验是否已有数据
        AssertUtils.isTrue(courseMapper.checkCourseExist(course.getName()),ErrorCode.CODE_203_NULL_COURSE_ISEXIST.getMessage());
    }
}
